using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace CapaAccesoDatos.Clases
{
    public class UsuarioCAD
    {
        //-------------------------------------------------------------------------------//
        // Propiedades de la Clase.                                                      //
        //-------------------------------------------------------------------------------//
        private int id;
        private int idTipoUsuario;
        private string username;
        private string password;
        private string nombres;
        private string apellidos;
        private bool activo;
        private bool bloqueado;
        private int idCarrera;
        private string matricula;

        //-------------------------------------------------------------------------------//
        // Accesores publicos de la Clase.                                               //
        //-------------------------------------------------------------------------------//
        public int Id
        {
            get { return this.id; }
        }
        public int IdTipoUsuario
        {
            get { return this.idTipoUsuario; }
        }
        public string Username
        {
            get { return this.username; }
        }
        public string Password
        {
            get { return this.password; }
        }
        public string Nombres
        {
            get { return this.nombres; }
        }
        public string Apellidos
        {
            get { return this.apellidos; }
        }
        public bool Activo
        {
            get { return this.activo; }
        }
        public bool Bloqueado
        {
            get { return this.bloqueado; }
            set { this.bloqueado = value; }
        }
        public int IdCarrera
        {
            get { return this.idCarrera; }
        }
        public string Matricula
        {
            get { return this.matricula; }
        }

        //-------------------------------------------------------------------------------//
        // Constructores de la Clase.                                                    //
        //-------------------------------------------------------------------------------//
        private UsuarioCAD(int Id, int Id_Tipo_Usuario, string Username, string Password, string Nombres, string Apellidos, bool Activo, bool Bloqueado, int Id_Carrera, string Matricula)
        {
            this.id = Id;
            this.idTipoUsuario = Id_Tipo_Usuario;
            this.username = Username;
            this.password = Password;
            this.nombres = Nombres;
            this.apellidos = Apellidos;
            this.activo = Activo;
            this.bloqueado = Bloqueado;
            this.idCarrera = Id_Carrera;
            this.matricula = Matricula;
        }

        //-------------------------------------------------------------------------------//
        //Metodos de la interface(despreciada a favor de metodos estaticos)              //
        //-------------------------------------------------------------------------------//
        public static void Save(UsuarioCAD Objeto)
        {
            String SqlCommand = "INSERT INTO " + Constantes.Tablas.Usuario.Nombre + " (" 
                              + Constantes.Tablas.Usuario.Campo_ID_Tipo_Usuario + ", " + Constantes.Tablas.Usuario.Campo_Username + ", "
                              + Constantes.Tablas.Usuario.Campo_Password + ", " + Constantes.Tablas.Usuario.Campo_Nombres + ", "
                              + Constantes.Tablas.Usuario.Campo_Apellidos + ", " + Constantes.Tablas.Usuario.Campo_Activo + ", "
                              + Constantes.Tablas.Usuario.Campo_Bloqueado + ", " + Constantes.Tablas.Usuario.Campo_ID_Carrera + ", "
                              + Constantes.Tablas.Usuario.Campo_Matricula + ") VALUES (" 
                              + Objeto.IdTipoUsuario.ToString() + ", '" + Objeto.Username.Trim() + "', '" + Objeto.Password.Trim() + "', '"
                              + Objeto.Nombres.Trim() + "', '" + Objeto.Apellidos.Trim() + "', " + Objeto.Activo.ToString() + ", "
                              + Objeto.Bloqueado.ToString() + ", " + Objeto.IdCarrera.ToString() + ", '" + Objeto.Matricula.Trim() + "')";
            //Sentencia:
            /*INSERT INTO Tabla (Columna1, Columna2...) 
             VALUES (Registro1, Registro2....); */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Comando.ExecuteNonQuery();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuariosCAD.Save(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return;
        }
        public static void Update(UsuarioCAD Objeto)
        {
            String SqlCommand = "UPDATE " + Constantes.Tablas.Usuario.Nombre + " SET " +
                                Constantes.Tablas.Usuario.Campo_ID_Tipo_Usuario + "=" + Objeto.IdTipoUsuario.ToString() + ", " +
                                Constantes.Tablas.Usuario.Campo_Username + "='" + Objeto.Username.Trim() + "', " +
                                Constantes.Tablas.Usuario.Campo_Password + "='" + Objeto.Password.Trim() + "', " +
                                Constantes.Tablas.Usuario.Campo_Nombres + "='" + Objeto.Nombres.Trim() + "', " +
                                Constantes.Tablas.Usuario.Campo_Apellidos + "='" + Objeto.Apellidos.Trim() + "', " +
                                Constantes.Tablas.Usuario.Campo_Activo + "='" + Objeto.Activo.ToString() + "', " +
                                Constantes.Tablas.Usuario.Campo_Bloqueado + "='" + Objeto.Bloqueado.ToString() + "', " +
                                Constantes.Tablas.Usuario.Campo_ID_Carrera + "=" + Objeto.IdCarrera.ToString() + ", " +
                                Constantes.Tablas.Usuario.Campo_Matricula + "='" + Objeto.Matricula.Trim() + "' WHERE " +
                                Constantes.Tablas.Usuario.Campo_Id + " = " + Objeto.Id.ToString();
            //Sentencia:
            /*UPDATE Tabla SET Campo1 = Registro1, Campo2 = Registro2.... 
             WHERE Id (de la tabla) = Id; */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Comando.ExecuteNonQuery();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuariosCAD.Update(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return;
        }
        public static void Delete(UsuarioCAD Objeto)
        {
            String SqlCommand = "DELETE FROM " + Constantes.Tablas.Usuario.Nombre +
                                " WHERE " + Constantes.Tablas.Usuario.Campo_Id + " = " + Objeto.Id.ToString();
            //Sentencia:
            /*DELETE FROM Tabla WHERE Id (de la tabla) = Id; */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Comando.ExecuteNonQuery();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuariosCAD.Delete(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return;
        }

        //-------------------------------------------------------------------------------//
        // Estos son los metodos especiales para el uso de la Capa de Lenguaje de Negocios
        //-------------------------------------------------------------------------------//
        public static UsuarioCAD BuscarPorId(int Id)
        {
            UsuarioCAD Retorno = null;
            String SqlCommand = " SELECT * FROM " + Constantes.Tablas.Usuario.Nombre +
                                " WHERE " + Constantes.Tablas.Usuario.Campo_Id +
                                " = " + Id.ToString();
            //La sentencia es
            /* SELECT * FROM UsuariosCAD WHERE Id = :P1
             * Donde :P1 es el numero del Id! */

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlDataReader Cursor = null;
            SqlTransaction Tx = null;

            //La sentencia es
            /*
             * SELECT * FROM Usuarios WHERE Id = :P1
             * Donde :P1 es el numero del Id! */

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();
                Comando.Transaction = Tx;
                Cursor = Comando.ExecuteReader(CommandBehavior.SingleRow);

                while (Cursor.Read())
                {
                    Retorno = new UsuarioCAD(Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_Id]),
                                              Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_ID_Tipo_Usuario]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Username]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Password]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Nombres]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Apellidos]),
                                              Convert.ToBoolean(Cursor[Constantes.Tablas.Usuario.Campo_Activo]),
                                              Convert.ToBoolean(Cursor[Constantes.Tablas.Usuario.Campo_Bloqueado]),
                                              Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_ID_Carrera]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Matricula]));
                }

                Cursor.Close();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuariosCAD.BuscarPorId(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return Retorno;
        }

        public static DataSet BuscarUsuariosEnLista(List<int> Elementos, int Id)
        {
            DataSet Resultado = new DataSet();
            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlDataAdapter Adaptador = new SqlDataAdapter();
            SqlCommand ComandoSql = new SqlCommand("SELECT * FROM " + Constantes.Tablas.Usuario.Nombre +
                                " WHERE " + Constantes.Tablas.Usuario.Campo_Id +
                                " IN (", Conexion);
            //La sentencia es
            /*
             * SELECT * FROM Usuarios WHERE Id IN :P1
             * Donde :P1 es el numero del Id! */

            SqlTransaction Tx = null;

            for (int i = 0; i < Elementos.Count; i++)
            {
                if (i == 0)
                    ComandoSql.CommandText += Elementos[i].ToString();
                else
                    ComandoSql.CommandText += "," + Elementos[i].ToString();
            }
            ComandoSql.CommandText += ")";

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();

                Adaptador.SelectCommand = ComandoSql;
                Adaptador.SelectCommand.Transaction = Tx;
                Adaptador.Fill(Resultado, Constantes.Tablas.Usuario.Nombre);
            }
            catch (Exception Ex)
            {
                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuariosCAD.BuscarUsuarioEnLista(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                ComandoSql.Dispose();
                Conexion.Dispose();
                Adaptador.Dispose();
            }
            return Resultado;
        }

        public static UsuarioCAD BuscaPorUserName(string UserName)
        {
            UsuarioCAD Retorno = null;
            String SqlCommand = " SELECT * FROM " + Constantes.Tablas.Usuario.Nombre +
                                " WHERE " + Constantes.Tablas.Usuario.Campo_Username +
                                "='" + UserName.Trim() + "'";
            //Sentencia
            /*SELECT * FROM Usuarios WHERE Username = UserName(recivido)*/

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlDataReader Cursor = null;
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();

                Comando.Transaction = Tx;
                Cursor = Comando.ExecuteReader(CommandBehavior.SingleRow);

                while (Cursor.Read())
                {
                    Retorno = new UsuarioCAD(Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_Id]),
                                              Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_ID_Tipo_Usuario]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Username]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Password]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Nombres]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Apellidos]),
                                              Convert.ToBoolean(Cursor[Constantes.Tablas.Usuario.Campo_Activo]),
                                              Convert.ToBoolean(Cursor[Constantes.Tablas.Usuario.Campo_Bloqueado]),
                                              Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_ID_Carrera]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Matricula]));
                }

                Cursor.Close();
                Tx.Commit();
            }
            catch (Exception Ex)
            {
                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuariosCAD.BuscarPorUserName(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }
            return Retorno;
        }

        public static UsuarioCAD BuscaPorMatricula(string Matricula)
        {
            UsuarioCAD Retorno = null;
            String SqlCommand = " SELECT * FROM " + Constantes.Tablas.Usuario.Nombre +
                                " WHERE " + Constantes.Tablas.Usuario.Campo_Matricula +
                                " = '" + Matricula.Trim() + "'";
            //Sentencia
            /*SELECT * FROM Usuarios WHERE Username = UserName(recivido)*/

            SqlConnection Conexion = new SqlConnection(Constantes.ConnectionString);
            SqlCommand Comando = new SqlCommand(SqlCommand, Conexion);
            SqlDataReader Cursor = null;
            SqlTransaction Tx = null;

            try
            {
                Conexion.Open();
                Tx = Conexion.BeginTransaction();

                Comando.Transaction = Tx;
                Cursor = Comando.ExecuteReader(CommandBehavior.SingleRow);

                while (Cursor.Read())
                {
                    Retorno = new UsuarioCAD(Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_Id]),
                                              Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_ID_Tipo_Usuario]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Username]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Password]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Nombres]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Apellidos]),
                                              Convert.ToBoolean(Cursor[Constantes.Tablas.Usuario.Campo_Activo]),
                                              Convert.ToBoolean(Cursor[Constantes.Tablas.Usuario.Campo_Bloqueado]),
                                              Convert.ToInt32(Cursor[Constantes.Tablas.Usuario.Campo_ID_Carrera]),
                                              Convert.ToString(Cursor[Constantes.Tablas.Usuario.Campo_Matricula]));
                }

                Cursor.Close();
                Tx.Commit();
            }
            catch (Exception Ex)
            {

                if (Cursor != null)
                    Cursor.Close();

                Tx.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuariosCAD.BuscarPorMatricula(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                Conexion.Close();
                Comando.Dispose();
                Conexion.Dispose();
            }

            return Retorno;
        }

        public static UsuarioCAD CrearUsuarioCAD(int Id, int Id_Tipo_Usuario, string Username, string Password, string Nombres, string Apellidos, bool Activo, bool Bloqueado, int Id_Carrera, string Matricula)
        { 
            return new UsuarioCAD(Id, Id_Tipo_Usuario, Username, Password, Nombres, Apellidos, Activo, Bloqueado, Id_Carrera, Matricula);
        }


        //17-10-2008 franklin 
        //Devuelve todas las sanciones de un usuario dado su ID.
        public static List<SancionCAD> GetSanciones(int idUsuario)
        {
            List<SancionCAD> result = new List<SancionCAD>();

            string selectcmd = "SELECT * FROM " + Constantes.Tablas.Sanciones.Nombre +
                               " WHERE " + Constantes.Tablas.Sanciones.Campo_IdUsuario +
                               " = " + idUsuario.ToString();

            SqlConnection connection = new SqlConnection(Constantes.ConnectionString);
            SqlCommand command = new SqlCommand(selectcmd, connection);
            SqlDataReader cursor = null;
            SqlTransaction transaccion = null;

            try
            {
                connection.Open();
                transaccion = connection.BeginTransaction();
                command.Transaction = transaccion;
                cursor = command.ExecuteReader(CommandBehavior.Default);

                while (cursor.Read())
                {
                    result.Add(SancionCAD.BuscarPorId(Convert.ToInt32(cursor[Constantes.Tablas.Sanciones.Campo_Id])));
                }
                cursor.Close();
                transaccion.Commit();
            }

            catch (Exception Ex)
            {
                if (cursor != null)
                    cursor.Close();

                transaccion.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuarioCAD.GetSanciones(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                connection.Close();
                command.Dispose();
                connection.Dispose();
            }
            return result;
        }

        public static List<String> GetAllTypes()
        {
            List<TipoUsuarioCAD> result = new List<TipoUsuarioCAD>();

            string selectcmd = "SELECT * FROM " + Constantes.Tablas.Tipousuario.Nombre;

            SqlConnection connection = new SqlConnection(Constantes.ConnectionString);
            SqlCommand command = new SqlCommand(selectcmd, connection);
            SqlDataReader cursor = null;
            SqlTransaction transaccion = null;

            try
            {
                connection.Open();
                transaccion = connection.BeginTransaction();
                command.Transaction = transaccion;
                cursor = command.ExecuteReader(CommandBehavior.Default);

                while (cursor.Read())
                {
                    result.Add(new TipoUsuarioCAD(Convert.ToInt32(cursor[Constantes.Tablas.Tipousuario.Campo_Id]),
                                                  Convert.ToString(cursor[Constantes.Tablas.Tipousuario.Campo_Descripcion])));
                }
                cursor.Close();
                transaccion.Commit();
            }

            catch (Exception Ex)
            {
                if (cursor != null)
                    cursor.Close();

                transaccion.Rollback();
                throw new System.Exception("ERROR: Se ha producido un error en la conexion con la base de datos." +
                           "FUNCION: UsuarioCAD.GetAllTypes(<args>)\n " +
                           "INNEREXCEPT:" + Ex.Message, Ex);
            }
            finally
            {
                connection.Close();
                command.Dispose();
                connection.Dispose();
            }

            List<String> ReturnValue = new List<String>();
            foreach (TipoUsuarioCAD Tipo in result)
            {
                ReturnValue.Add(Tipo.Descripcion);
            }
            return ReturnValue;
        }
    
    }
}
